package cn.edu.sjtu.se.dslab.component.method.util;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;

import cn.edu.sjtu.se.dslab.component.data.DataType;
import cn.edu.sjtu.se.dslab.component.data.DomainEntity;
import cn.edu.sjtu.se.dslab.component.method.ComponentInterface;
import cn.edu.sjtu.se.dslab.component.method.InterfaceMethod;
import cn.edu.sjtu.se.dslab.pojo.CodeGenerator;
import cn.edu.sjtu.se.dslab.service.IDataTypeService;
import cn.edu.sjtu.se.dslab.service.IDomainEntityService;
import cn.edu.sjtu.se.dslab.service.IInterfaceMethodService;
import cn.edu.sjtu.se.dslab.util.Const;
import cn.edu.sjtu.se.dslab.util.Util;

@Service("interfaceGenerator")
public class InterfaceGenerator extends CodeGenerator{
	
	@Resource(name = "interfaceMethodService")
	IInterfaceMethodService interfaceMethodService;
	
	@Resource(name = "dataTypeService")
	IDataTypeService dataTypeService;
	
	@Resource(name = "domainEntityService")
	IDomainEntityService domainEntityService;
	
	private final static String FILE_ID = "fileID";
	
	private final static String FUNCTION_LIST = "functionList";

	private final static String HEADER_LIST = "headerList";
	
	private final static String Interface_TemplateFile = "interface.vm";
	
	
	
	public InterfaceGenerator() {
		super();
	}
	
	public InterfaceGenerator(String templateFile) {
		super(templateFile);
	}

	public boolean generateInterface(ComponentInterface cInterface,String targetFile)throws IOException{
		template = ve.getTemplate(Interface_TemplateFile);
		
		String fileId = cInterface.getName().replace(" ", "_").toUpperCase()+"_H";
		vc.put(FILE_ID, fileId);
		
		Set<String> headerList = new HashSet<String>();
		Set<InterfaceMethod> methods = cInterface.getInterfaceMethods();
		for (InterfaceMethod interfaceMethod : methods) {
			DomainEntity returnType = interfaceMethod.getReturnType();
			DataType tempType = dataTypeService.getDataTypeById(returnType.getId());
			if (tempType == null || !tempType.getCategory().equals(Const.DATA_TYPE_BASIC)) {
				String temp = returnType.getName()
						.replace(" ", "_").toLowerCase();
				headerList.add("#include \"" + temp + ".h\"");
			}
			
			String depTypes = interfaceMethod.getDepType();
			if (depTypes != null &&!depTypes.equals("")) {
				String type[] = depTypes.split(";");
				Set<String> tempSet = new HashSet<String>();
				for (String string : type) {
					tempSet.add(string);
				}
				for (String string : tempSet) {
					DomainEntity tempEntity =  domainEntityService.getDomainEntityById(Long.parseLong(string));
					DataType temp =  dataTypeService.getDataTypeById(Long.parseLong(string));
					if (temp == null || !temp.getCategory().equals(Const.DATA_TYPE_BASIC)) {
						String head = tempEntity.getName()
								.replace(" ", "_").toLowerCase();
						headerList.add("#include \"" + head + ".h\"");
					}
				}
			}
			
		}
		
		vc.put(HEADER_LIST,headerList);
		
		Set<String> functionList = new HashSet<String>();
		if (cInterface.getInterfaceMethods() != null) {
			for (InterfaceMethod method:methods) {
				String temp = method.getMethodSigniture();
				if (!temp.endsWith(";")) {
					temp = temp+";";
				}
				functionList.add(temp);
			}
		}
		vc.put(FUNCTION_LIST, functionList);
		
		FileWriter fWriter = null;
		try {
			File writeFile = getFile(targetFile);
			fWriter = new FileWriter(writeFile);
			if (template != null) {
				template.merge(vc, fWriter);
			}		
		}finally {
			try {
				fWriter.flush();
				fWriter.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return true;
	}
	
	public boolean generateInterface(ComponentInterface cInterface) throws IOException{
		String interfaceName = Util.getInterfaceName(cInterface);
		String interfacePath = Const.INTERFACE_GENERATE_PATH
				+ interfaceName;
		String interfaceRealPath = Const.ABSOLUTE_GENERATE_PATH
				+ interfacePath;
		File file = new File(interfaceRealPath);
		if (!file.exists()) {
			return generateInterface(cInterface, interfaceRealPath);
		}else {
			return true;
		}
		
		
	}
	public void deleteInterfaceFile(ComponentInterface cInterface) throws IOException{
		String interfaceName = Util.getInterfaceName(cInterface);
		String interfacePath = Const.INTERFACE_GENERATE_PATH
				+ interfaceName;
		String interfaceRealPath = Const.ABSOLUTE_GENERATE_PATH
				+ interfacePath;
		File file = new File(interfaceRealPath);
		if (file.exists()) {
			file.delete();
		}	
	}
}
